

# 十字星
def is_doji(row):
    open_price = row['open']
    close_price = row['close']
    high_price = row['high']
    low_price = row['low']
    return high_price-low_price>abs(open_price-close_price)*2 and _is_entity_candle(row,max_percentage=0.6) and row['high'] > max(row['open'],row['close']) and min(row['open'],row['close'])> row['low']

# 星线
def is_star(row):
    open_price = row['open']
    close_price = row['close']
    high_price = row['high']
    low_price = row['low']
    # 星线的条件：实体非常小，影线较长
    # 实体非常小可以定义为开盘价和收盘价非常接近
    # 影线较长可以定义为实体长度与影线长度的比例
    body_length = abs(open_price - close_price)
    up_shadow_length = high_price - max(close_price , open_price)
    down_shadow_length = min(close_price , open_price) - low_price
    # 实体长度与影线长度的比例，这里我们设定一个阈值，例如实体长度小于影线长度的1/4
    return body_length < (up_shadow_length + down_shadow_length) / 4

# 长上影线
def is_shooting_star(row):
    open_price = row['open']
    close_price = row['close']
    high_price = row['high']
    low_price = row['low']
    # 长上影线的条件：实体较小，上影线非常长，下影线很短或不存在
    # 实体较小可以定义为开盘价和收盘价非常接近
    # 上影线非常长可以定义为上影线长度远大于实体长度
    # 下影线很短或不存在可以定义为下影线长度小于某个阈值
    body_length = abs(open_price - close_price)
    up_shadow_length = high_price - max(open_price,close_price)
    down_shadow_length = min(open_price,close_price) - low_price
    # 这里我们设定一个阈值，例如上影线长度是实体长度的3倍，下影线长度小于实体长度的1/4
    return body_length < up_shadow_length / 3 and down_shadow_length < up_shadow_length / 4 and (up_shadow_length/open_price) *100 >3

# 长下影线（Dragonfly Doji）
def is_dragonfly_doji(row):
    open_price = row['open']
    close_price = row['close']
    high_price = row['high']
    low_price = row['low']
    # 长下影线的条件：实体非常小，位于整个价格范围的下端，下影线非常长
    body_length = abs(open_price - close_price)
    up_shadow_length = high_price - max(open_price,close_price)
    down_shadow_length = min(open_price,close_price) - low_price
    return (body_length < down_shadow_length / 3) and (up_shadow_length < down_shadow_length / 4) and ((down_shadow_length / open_price) * 100 > 3)




# 锤子线
def is_hammer(row):
    open_price = row['open']
    close_price = row['close']
    high_price = row['high']
    low_price = row['low']
    # 锤子线的条件：实体较小，下影线非常长，上影线很短或不存在
    # 实体较小可以定义为开盘价和收盘价非常接近
    # 下影线非常长可以定义为下影线长度远大于实体长度
    # 上影线很短或不存在可以定义为上影线长度小于某个阈值
    up_shadow_length = high_price - max(open_price,close_price)
    down_shadow_length = min(open_price,close_price) - low_price
    # 这里我们设定一个阈值，例如下影线长度是实体长度的3倍，上影线长度小于实体长度的1/4
    return _is_entity_candle(row,max_percentage=1)  and down_shadow_length > up_shadow_length * 5

# 倒锤头
def is_inverted_hammer(row):
    open_price = row['open']
    close_price = row['close']
    high_price = row['high']
    low_price = row['low']
    # 倒锤头的条件：实体较小，上影线较长，下影线较短或不存在
    return (high_price - open_price) > (close_price - low_price) and \
        abs(open_price - close_price) < (high_price - low_price) * 0.05
# 小阴线
def is_little_black_candle(row,max_percentage=2.5):
    open_price = row['open']
    close_price = row['close']
    return close_price < open_price and _is_entity_candle(row,max_percentage=max_percentage)
# 中阴线
def is_medium_black_candle(row, min_percentage=2.5, max_percentage=6):
    open_price = row['open']
    close_price = row['close']
    return close_price < open_price and _is_entity_candle(row,min_percentage=min_percentage,max_percentage=max_percentage)


# 大阴线
def is_long_black_candle(row):
    open_price = row['open']
    close_price = row['close']
    # 大阴线的条件：实体很长，表示价格大幅下跌
    return close_price < open_price and _is_entity_candle(row,min_percentage=6)
# 小阳线
def is_little_white_candle(row,max_percentage=2.5):
    open_price = row['open']
    close_price = row['close']
    return close_price > open_price and _is_entity_candle(row,max_percentage=max_percentage)
# 中阳线
def is_medium_white_candle(row, min_percentage=2.5, max_percentage=6):
    open_price = row['open']
    close_price = row['close']
    return close_price > open_price and _is_entity_candle(row,min_percentage=min_percentage,max_percentage=max_percentage)

# 大阳线
def is_long_white_candle(row):
    open_price = row['open']
    close_price = row['close']
    # 大阳线的条件：实体很长，表示价格大幅上涨
    return close_price > open_price and _is_entity_candle(row,min_percentage=6)

# 风高浪急线
def is_windy_wavey_candle(row):
    open_price = row['open']
    close_price = row['close']
    high_price = row['high']
    low_price = row['low']

    # 风高浪急的条件：实体较小，上下影线都较长
    # 这里我们设定一个阈值来定义“较长”，例如影线长度至少是实体长度的两倍
    body_length = abs(open_price - close_price)
    up_shadow_length = high_price - close_price if close_price > open_price else close_price - high_price
    down_shadow_length = close_price - low_price if close_price > open_price else low_price - close_price
    return ((up_shadow_length > body_length * 2) and (down_shadow_length > body_length * 2)
            and ((down_shadow_length/open_price)  * 100 >2) and ((up_shadow_length/open_price) * 100 >2))

def _is_entity_candle(row, min_percentage = None,max_percentage = None):
    open_price = row['open']
    close_price = row['close']
    # 计算实体的长度
    body_length = abs(open_price - close_price)
    if min_percentage is None:
        return (body_length / open_price)*100 <= max_percentage
    elif max_percentage is None:
        return (body_length / open_price)*100 >= min_percentage
    else:
        return min_percentage <= (body_length / open_price)*100 <= max_percentage


if __name__ == '__main__':
    # 示例用法
    pass

